index.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { PermissionAction } from '@supabase/shared-types/out/constants'
  2. import { useFeatureFlags, useFlag, useParams } from 'common'
  3. import { useRouter } from 'next/router'
  4. import { parseAsBoolean, useQueryState } from 'nuqs'
  5. import { useEffect } from 'react'
  6. import { LogoLoader } from 'ui'
  7. import { ObservabilityOverview } from '@/components/interfaces/Observability/ObservabilityOverview'
  8. import { CreateReportModal } from '@/components/interfaces/Reports/CreateReportModal'
  9. import DefaultLayout from '@/components/layouts/DefaultLayout'
  10. import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout'
  11. import ProductEmptyState from '@/components/to-be-cleaned/ProductEmptyState'
  12. import { useContentQuery } from '@/data/content/content-query'
  13. import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
  14. import { useProfile } from '@/lib/profile'
  15. import type { NextPageWithLayout } from '@/types'
  16. export const UserReportPage: NextPageWithLayout = () => {
  17. const router = useRouter()
  18. const { ref } = useParams()
  19. const { profile } = useProfile()
  20. const { hasLoaded: flagsLoaded } = useFeatureFlags()
  21. const showOverview = useFlag('observabilityOverview')
  22. const [showCreateReportModal, setShowCreateReportModal] = useQueryState(
  23. 'newReport',
  24. parseAsBoolean.withDefault(false).withOptions({ history: 'push', clearOnDefault: true })
  25. )
  26. const {
  27. isPending: isLoading,
  28. isSuccess,
  29. data,
  30. } = useContentQuery({
  31. projectRef: ref,
  32. type: 'report',
  33. })
  34. useEffect(() => {
  35. if (!isSuccess) return
  36. if (!flagsLoaded) return // Wait for flags to load before checking redirect
  37. if (showOverview) return // Don't redirect if overview is enabled
  38. const reports = data.content
  39. .filter((x) => x.type === 'report')
  40. .sort((a, b) => a.name.localeCompare(b.name))
  41. if (reports.length >= 1) router.replace(`/project/${ref}/observability/${reports[0].id}`)
  42. if (reports.length === 0) router.replace(`/project/${ref}/observability/api-overview`)
  43. }, [isSuccess, data, router, ref, showOverview, flagsLoaded])
  44. const { can: canCreateReport } = useAsyncCheckPermissions(
  45. PermissionAction.CREATE,
  46. 'user_content',
  47. {
  48. resource: { type: 'report', owner_id: profile?.id },
  49. subject: { id: profile?.id },
  50. }
  51. )
  52. // Wait for flags to load before rendering to avoid flashing wrong page
  53. if (!flagsLoaded || isLoading) {
  54. return <LogoLoader />
  55. }
  56. // Show overview page if feature flag is enabled
  57. if (showOverview) {
  58. return <ObservabilityOverview />
  59. }
  60. return (
  61. <div className="h-full w-full">
  62. <>
  63. <ProductEmptyState
  64. title="Observability"
  65. ctaButtonLabel="New custom report"
  66. onClickCta={() => {
  67. setShowCreateReportModal(true)
  68. }}
  69. disabled={!canCreateReport}
  70. disabledMessage="You need additional permissions to create a report"
  71. >
  72. <p className="text-foreground-light text-sm">Create custom reports for your projects.</p>
  73. <p className="text-foreground-light text-sm">
  74. Get a high level overview of your network traffic, user actions, and infrastructure
  75. health.
  76. </p>
  77. </ProductEmptyState>
  78. <CreateReportModal
  79. visible={showCreateReportModal}
  80. onCancel={() => setShowCreateReportModal(false)}
  81. afterSubmit={() => setShowCreateReportModal(false)}
  82. />
  83. </>
  84. </div>
  85. )
  86. }
  87. UserReportPage.getLayout = (page) => (
  88. <DefaultLayout>
  89. <ObservabilityLayout title="Overview">{page}</ObservabilityLayout>
  90. </DefaultLayout>
  91. )
  92. export default UserReportPage